;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname |lab 1 adam alex 1-6-09|) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "htdp") (lib "testing.ss" "teachpack" "htdp") (lib "world.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "image.ss" "teachpack" "htdp") (lib "testing.ss" "teachpack" "htdp") (lib "world.ss" "teachpack" "htdp")))))
#| 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Lab1 January 6th 2009
Adam Blackwell
Alex Pilat
James Morin
Richard Zelinsky
|#

#|
1.1 Designing Programs with Accumulators
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

|#

; sum-reg : [listof Number] -> Number
; Adds up a list of numbers.
(define (sum-reg lon)
  (if (empty? lon) 0
      (+ (first lon) (sum-reg (rest lon)))))

(check-expect (sum-reg (list 1 2 3)) 6)

; sum-reg adds in the order the list is given, which is 
; left to right. (foldr)

(define l1 '(1 2 3 4 5))
(define l2 (list 1 #i1.234 e pi 5))
(define l3 '(1 2 3 4))



;; From the book:
;; --------------
;; For the first example, consider the function sum:

;; sum : (listof number)  ->  number
;; to compute the sum of the numbers on alon
;; structural recursion 
#;(define (sum alon)
    (cond
      [(empty? alon) 0]
      [else (+ (first alon) (sum (rest alon)))]))
;; Here is the first step toward an accumulator version:

;; sum : (listof number)  ->  number
;; to compute the sum of the numbers on alon0
#;(define (sum alon0)
    (local (;; accumulator ... 
            (define (sum-a alon accumulator)
              (cond
                [(empty? alon) ...]
                [else
                 ... (sum-a (rest alon) ... ( first alon) ... accumulator)
                 ... ])))
      (sum-a alon0 ...)))

#|
The Regular funtion is like forldr

-- What is the order of the additions now?
The accumulator function is like the add left which uses foldl 
which is an accumulator by nature.
|#

#|
1.2 Exploring the commutativity and associativity of other computations.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

Next we design two functions that compute the factorial of a given number.
We recall that we can dene factorial of 5 as one of the following two values:
5! = 1 . 2 . 3 . 4 . 5
5! = 5 . 4 . 3 . 2 . 1
Design the functions fac-L->R and fac-R->L that compute a factorial of
the given number.
For help consult HtDP, exercise 31.3.2 and the text before this exercise.
Run the exercise 31.3.2 and verify the book's assertions about the times
needed to compute the two results.
|#

; facR : Number -> Number
; computer factorial of the number to the right

(define (facR n)
  (cond [(zero? n) 1]
        [else (* n (facR (sub1 n)))]))

(define (facL-acum a n)
  (cond [(= a n) 1]
        [else (* (add1 a) (facL-acum (add1 a) n))]))

; facL : Number -> Number
; computer factorial of the number to the left
(define (facL n)
  (facL-acum 1 n))

(check-expect (facL 5) 120)
(check-expect (facR 5) 120)

#|
1.3 Homework partners
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
We stop now to set up the homework partner teams.
|#

#|
1.4 The need for accumulators
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
In the lectures we had the following problem. We were given information
about a radio show: name, total running time in minutes, and a list of ads
to run during the show, where for each ad we were given its name, the
running time in minutes and the profit it generates in dollars.
Here is the program we produced:
|#


;; Data definitions
;; A Radio Show (RS) is make-rs String Number [Listof ad]
(define-struct rs (name minutes ads))

;; An Ad is (make-ad String Number Number)
(define-struct ad (name minutes profit))

;; Examples of data:
(define ipod-ad (make-ad "ipod" 2 100))
(define ms-ad (make-ad "ms" 1 500))
(define xbox-ad (make-ad "xbox" 2 300))
(define news-ads (list ipod-ad ms-ad ipod-ad xbox-ad))
(define game-ads (list ipod-ad ms-ad ipod-ad ms-ad xbox-ad ipod-ad))
(define bad-ads (list ipod-ad ms-ad ms-ad ipod-ad xbox-ad ipod-ad))
(define news (make-rs "news" 60 news-ads))
(define game (make-rs "game" 120 game-ads))

;; computes the total time for all ads in the given list
;; total-time: [Listof Ad] -> Number
#;(define (total-time adlist)
    (cond
      [(empty? adlist) 0]
      [else (+ (ad-minutes (first adlist))
               (total-time (rest adlist)))]))



;; how much time is there for the show itself
;; show-time: RS -> Number
(define (show-time an-rs)
  (- (rs-minutes an-rs) (total-time (rs-ads an-rs))))

(check-expect (show-time news) 53)
(check-expect (show-time game) 110)

#|
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
1. Convert the total-time function to total-time-acc that uses the accumulator.
|#

;; Accumulator
(define (total-time-acum a adlist)
  (cond
    [(empty? adlist) a]
    [else (total-time-acum (+ a (ad-minutes (first adlist)))
                           (rest adlist))]))

;; compute the total time for all ads in the given list
;; total-time-accum: [Listof Ad] -> Number
(define (total-time adlist)
  (total-time-acum 0 adlist))

(check-expect (total-time news-ads) 7)
(check-expect (total-time bad-ads) 10)
(check-expect (total-time game-ads) 10)

#|
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
2. Compute the total profit for the show using both the function we
get by following the design recipe and one that uses the accumulator.
(If you are running out of time, skip this, do it at home, and go on to
the last problem.)
|#

;; The invarient is that the accumulator represents the total profit 
;; of all ads that we've seen so far.
;; total-profit-acum : number [ListOf number] -> number
(define (total-profit-acum a adlist)
  (cond
    [(empty? adlist) a]
    [else (total-profit-acum (+ a (ad-profit (first adlist)))
                           (rest adlist))]))

;; compute the total profit for all ads in the given list
;; total-profit-accum: [Listof Ad] -> Number
(define (total-profit adlist)
  (total-profit-acum 0 adlist))

(check-expect (total-profit news-ads) 1000)
(check-expect (total-profit bad-ads) 1600)
(check-expect (total-profit game-ads) 1600)

#|
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
3. The show producer wants to make sure that the list of ads does not
repreat the same ad twice without having a different ad in between.
So, a list of ads (list ipod-ad ms-ad ipod-ad xbox-ad) is OK, but the list of
ads (list ipod-ad ms-ad ms-ad ipod-ad xbox-ad ipod-ad) is not acceptable,
because two ms ads are run without a break in between.
Design the function no-repeat that produces true if the list of ads is
acceptable and produces false otherwise.
Do you need an accumulator here? Why? Can you write the function
without one?
Save all your workthe next lab will build on the work you have done
|#

;; no-repeat : [listof ad] -> boolean
;; checks to make sure no two similar ads are next to each other
(define (no-repeat loa)
  (cond [(empty? (rest loa)) true]
        [(equal? (first loa) (first (rest loa))) false]
        [else (no-repeat (rest loa))]))


(check-expect (no-repeat (list ipod-ad ms-ad ipod-ad xbox-ad)) true)
(check-expect (no-repeat (list ipod-ad ms-ad ms-ad ipod-ad xbox-ad ipod-ad))
              false)
(check-expect (no-repeat (list ipod-ad ms-ad ms-ad ipod-ad xbox-ad xbox-ad))
              false)
















